import java.util.ArrayList;
import java.util.StringTokenizer;


public class PaxosMessage {

	/*
	 * Build all the possible messages. Get constants from consts
	 */
	int proposalNum;
	String proposalValue;
	int highAcceptProposalNum;
	String highAcceptProposalValue;
	int highPrepareProposalNum;
	int senderId;
	String msgType;
	ArrayList<String > cmdParamList;
	int instanceId;
	String respToClient;
	int clientId;
 	
	public PaxosMessage()
	{
		
	}

	public PaxosMessage(byte[] byteData)
	{
		this(new String(byteData));
	}
	
	public PaxosMessage(String strMesg)
	{
		StringTokenizer mesgTokens = new StringTokenizer(strMesg,";");
		ArrayList<String> mesgTokenList = new ArrayList<String>();
		for (int i=0;i<PaxosConsts.PM_NUM_FIELDS;i++)
		{
			mesgTokenList.add(i, "");
		}
		int i=0;
		while(mesgTokens.hasMoreTokens())
		{
			mesgTokenList.set(i,mesgTokens.nextToken());
			i++;
		}
		msgType = mesgTokenList.get(PaxosConsts.PM_MSG_TYPE);
		senderId = Integer.parseInt(mesgTokenList.get(PaxosConsts.PM_SENDER_ID)); 
		proposalNum = Integer.parseInt(mesgTokenList.get(PaxosConsts.PM_PROPOSAL_NUM));
		proposalValue = mesgTokenList.get(PaxosConsts.PM_PROPOSAL_VAL);
		cmdParamList = strToArrayList(mesgTokenList.get(PaxosConsts.PM_CLIENT_CMD_LIST));
		clientId = Integer.parseInt(mesgTokenList.get(PaxosConsts.PM_CLIENT_ID));
		highAcceptProposalNum = Integer.parseInt(mesgTokenList.get(PaxosConsts.PM_HIGH_ACCEPT_PROP_NUM));
		highAcceptProposalValue = mesgTokenList.get(PaxosConsts.PM_HIGH_ACCEPT_PROP_VAL);
		instanceId = Integer.parseInt(mesgTokenList.get(PaxosConsts.PM_INSTANCE_ID));
		respToClient = mesgTokenList.get(PaxosConsts.PM_RESP_TO_CLIENT);
	}
	
	public ArrayList<String> strToArrayList(String str)
	{
		ArrayList<String> slist = null;		
		if (!str.equals(""))
		{
			// arraylist to string causes '[' and ']' to be adde. so removing them.
			String trimmedStr = str;
			slist = new ArrayList<String>();
			if (str.indexOf('[') != -1)
			{
				trimmedStr = str.substring(str.indexOf('[')+1, str.indexOf(']'));
			}
			StringTokenizer strTokens = new StringTokenizer(trimmedStr,",");
			while(strTokens.hasMoreElements())
			{
				slist.add(strTokens.nextToken());
			}
		}
		return slist;
	}
	
	public PaxosMessage(int proposalNum, String proposalValue) 
	{
		this.proposalNum = proposalNum;
		this.proposalValue = proposalValue;
	}
	
	
	public byte[] buildPaxosMsg(String msgType,int pid,int instanceId, int proposalNum,String proposalVal,
			ArrayList<String> clientCmdList, int highAcceptPropNum, String highAcceptPropVal,String respToClient, int clientId)
	{	
		String completeMsg = "";
		String[] completeMsgArray = new String[PaxosConsts.PM_NUM_FIELDS];
		for (int i=0;i<completeMsgArray.length;i++)
		{
			completeMsgArray[i] = " ";
		}
		completeMsgArray[PaxosConsts.PM_MSG_TYPE] = msgType;
		completeMsgArray[PaxosConsts.PM_SENDER_ID] = ((Integer)pid).toString();
		completeMsgArray[PaxosConsts.PM_INSTANCE_ID] = ((Integer)instanceId).toString();
		completeMsgArray[PaxosConsts.PM_PROPOSAL_NUM] = ((Integer)proposalNum).toString();
		completeMsgArray[PaxosConsts.PM_PROPOSAL_VAL] = proposalVal;
		completeMsgArray[PaxosConsts.PM_HIGH_ACCEPT_PROP_NUM] = ((Integer)highAcceptPropNum).toString();
		completeMsgArray[PaxosConsts.PM_HIGH_ACCEPT_PROP_VAL] = highAcceptPropVal;
		completeMsgArray[PaxosConsts.PM_CLIENT_ID] = ((Integer)clientId).toString();
		if (clientCmdList != null)
		{
			completeMsgArray[PaxosConsts.PM_CLIENT_CMD_LIST] = clientCmdList.toString();
		}
		completeMsgArray[PaxosConsts.PM_RESP_TO_CLIENT] = respToClient;
		                 
		for (int i=0; i<completeMsgArray.length-1;i++)
		{
			completeMsg+=completeMsgArray[i]+";";
		}
		completeMsg+=completeMsgArray[completeMsgArray.length-1];
		return completeMsg.getBytes();
	}
	
}